"""
Agent工厂类
提供统一的Agent创建和管理接口
"""

import os
import json
from typing import Dict, List, Type, Any, Optional, TYPE_CHECKING

if TYPE_CHECKING:
    from core.base_agent import BaseAgent


class AgentRegistry:
    """Agent注册器，管理所有可用的Agent类型"""
    
    _instance = None
    _agent_types: Dict[str, Type] = {}
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    @classmethod
    def register_agent(cls, name: str, agent_class: Type):
        """注册Agent类型"""
        cls._agent_types[name] = agent_class
        from tools.utils import EnhancedOutput, OutputType
        EnhancedOutput.display(f"注册Agent类型: {name} -> {agent_class.__name__}", OutputType.INFO)
    
    @classmethod
    def get_agent_class(cls, name: str) -> Optional[Type]:
        """获取Agent类"""
        return cls._agent_types.get(name)
    
    @classmethod
    def list_agents(cls) -> List[str]:
        """列出所有已注册的Agent类型"""
        return list(cls._agent_types.keys())
    
    @classmethod
    def get_agent_info(cls, name: str) -> Optional[Dict[str, Any]]:
        """获取Agent信息"""
        if name not in cls._agent_types:
            return None
        
        agent_class = cls._agent_types[name]
        return {
            "name": name,
            "class_name": agent_class.__name__,
            "module": agent_class.__module__,
            "base_class": [base.__name__ for base in agent_class.__bases__],
            "description": agent_class.__doc__ or "无描述"
        }


class AgentFactory:
    """Agent工厂类，负责创建不同类型的Agent实例"""
    
    def __init__(self):
        self.registry = AgentRegistry()
        self._load_default_agents()
    
    def _load_default_agents(self):
        """加载默认的Agent类型"""
        # 注册基础Agent类型
        from core.base_agent import ConversationalAgent, TaskOrientedAgent
        self.registry.register_agent("conversational", ConversationalAgent)
        self.registry.register_agent("task_oriented", TaskOrientedAgent)
        
        # 加载自定义Agent
        self._discover_custom_agents()
    
    def _discover_custom_agents(self):
        """发现并注册自定义Agent"""
        try:
            agents_dir = "share/agents"
            if not os.path.exists(agents_dir):
                return
            
            # 扫描配置文件
            for file_name in os.listdir(agents_dir):
                if file_name.startswith("agent_") and file_name.endswith(".json"):
                    agent_name = file_name[6:-5]  # 去掉 "agent_" 和 ".json"
                    self._create_agent_class_from_config(agent_name)
        
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"发现自定义Agent失败: {str(e)}", OutputType.WARNING)
    
    def _create_agent_class_from_config(self, config_name: str):
        """从配置文件创建Agent类"""
        try:
            config_path = os.path.join("share/agents", f"agent_{config_name}.json")
            
            with open(config_path, "r", encoding="utf-8") as f:
                config = json.load(f)
            
            agent_config = config["agent"]
            agent_type = agent_config.get("agent_type", "conversational")
            
            # 延迟导入
            from core.base_agent import ConversationalAgent, TaskOrientedAgent
            
            # 根据类型创建对应的类
            if agent_type == "task_oriented":
                base_class = TaskOrientedAgent
            else:
                base_class = ConversationalAgent
            
            # 创建动态类
            class_name = f"{config_name.capitalize()}Agent"
            
            # 动态创建Agent类，提供chat方法的实现
            def chat_implementation(self, user_input: str, reset: bool = False) -> str:
                """聊天方法的默认实现"""
                if reset:
                    self.reset_conversation()
                
                self.messages.append({"role": "user", "content": user_input})
                
                try:
                    full_response = ""
                    for chunk in self.model.chat(self.messages):
                        full_response += chunk
                    
                    # 检查工具调用
                    tool_calls = self.parse_tool_calls(full_response)
                    
                    if tool_calls:
                        # 执行工具调用
                        tool_result = self.handle_tool_calls(tool_calls)
                        
                        # 将工具执行结果添加到对话中
                        self.messages.append({"role": "assistant", "content": full_response})
                        self.messages.append({"role": "user", "content": f"工具执行结果:\n{tool_result}"})
                        
                        # 获取最终响应
                        final_response = ""
                        for chunk in self.model.chat(self.messages):
                            final_response += chunk
                        
                        self.messages.append({"role": "assistant", "content": final_response})
                        self.update_memory(user_input, final_response)
                        return final_response
                    else:
                        # 没有工具调用，直接返回响应
                        self.messages.append({"role": "assistant", "content": full_response})
                        self.update_memory(user_input, full_response)
                        return full_response
                        
                except Exception as e:
                    from tools.utils import EnhancedOutput, OutputType
                    error_msg = f"{self.name} 对话出错: {str(e)}"
                    EnhancedOutput.display(error_msg, OutputType.ERROR)
                    return error_msg
            
            dynamic_class = type(
                class_name,
                (base_class,),
                {
                    "__doc__": agent_config.get("description", "自定义Agent"),
                    "_config_name": config_name,
                    "chat": chat_implementation
                }
            )
            
            # 注册到注册器
            self.registry.register_agent(config_name, dynamic_class)
            
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"创建Agent类失败 {config_name}: {str(e)}", OutputType.WARNING)
    
    def create_agent(self, agent_type: str, **kwargs) -> Optional:
        """创建Agent实例"""
        try:
            agent_class = self.registry.get_agent_class(agent_type)
            if agent_class is None:
                from tools.utils import EnhancedOutput, OutputType
                EnhancedOutput.display(f"未知的Agent类型: {agent_type}", OutputType.ERROR)
                return None
            
            # 创建实例
            if hasattr(agent_class, '_config_name'):
                # 动态创建的类
                agent = agent_class(agent_class._config_name)
            else:
                # 基础类，需要传入配置名
                config_name = kwargs.get('config_name', agent_type)
                agent = agent_class(config_name)
            
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"成功创建Agent: {agent.name} (类型: {agent_type})", OutputType.SUCCESS)
            return agent
            
        except Exception as e:
            from tools.utils import EnhancedOutput, OutputType
            EnhancedOutput.display(f"创建Agent失败: {str(e)}", OutputType.ERROR)
            return None
    
    def create_all_agents(self) -> Dict[str, Any]:
        """创建所有已注册的Agent"""
        agents = {}
        for agent_type in self.registry.list_agents():
            agent = self.create_agent(agent_type)
            if agent:
                agents[agent_type] = agent
        
        return agents
    
    def get_agent_configs(self) -> List[Dict[str, Any]]:
        """获取所有可用的Agent配置"""
        configs = []
        agents_dir = "share/agents"
        
        if os.path.exists(agents_dir):
            for file_name in os.listdir(agents_dir):
                if file_name.startswith("agent_") and file_name.endswith(".json"):
                    config_name = file_name[6:-5]
                    config_path = os.path.join(agents_dir, file_name)
                    
                    try:
                        with open(config_path, "r", encoding="utf-8") as f:
                            config_data = json.load(f)
                        
                        agent_config = config_data.get("agent", {})
                        configs.append({
                            "name": config_name,
                            "display_name": agent_config.get("name", config_name),
                            "description": agent_config.get("description", ""),
                            "version": agent_config.get("version", "1.0"),
                            "type": agent_config.get("agent_type", "conversational"),
                            "config_file": file_name
                        })
                    except Exception as e:
                        from tools.utils import EnhancedOutput, OutputType
                        EnhancedOutput.display(f"读取配置文件失败 {file_name}: {str(e)}", OutputType.WARNING)
        
        return configs
    
    def reload_agents(self):
        """重新加载所有Agent"""
        from tools.utils import EnhancedOutput, OutputType
        EnhancedOutput.display("重新加载Agent注册表...", OutputType.INFO)
        

        AgentRegistry._agent_types.clear()
        
        self._load_default_agents()
        
        EnhancedOutput.display("Agent重新加载完成", OutputType.SUCCESS)


_global_factory: Optional[AgentFactory] = None


def get_agent_factory() -> AgentFactory:
    """获取全局Agent工厂实例"""
    global _global_factory
    if _global_factory is None:
        _global_factory = AgentFactory()
    return _global_factory


def create_agent(agent_type: str, **kwargs) -> Optional:
    """便捷函数：创建Agent"""
    factory = get_agent_factory()
    return factory.create_agent(agent_type, **kwargs)


def list_available_agents() -> List[Dict[str, Any]]:
    """便捷函数：列出可用的Agent"""
    factory = get_agent_factory()
    return factory.get_agent_configs()